package com.mine.jzh3.oss.utils;

import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;
import java.util.Map;

/**
 * 文件转换工具类
 */
@Slf4j
public class FileConverter {
    /**
     * 文件类型（扩展名）与MIME类型映射
     */
    private static final Map<String, String> MIME_TYPE_MAP = MapUtil.<String, String>builder()
            .put("jpg", "image/jpeg")
            .put("jpeg", "image/jpeg")
            .put("png", "image/png")
            .put("gif", "image/gif")
            .put("pdf", "application/pdf")
            .put("txt", "text/plain")
            .put("zip", "application/zip")
            .put("docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document")
            .put("xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
            .put("mp4", "video/mp4")
            .build();

    /**
     * 将 BufferedImage 转换为 InputStream，用于上传
     *
     * @param image  BufferedImage 对象
     * @param format 图片格式，如 "png", "jpg"
     * @return 转换后的 InputStream
     */
    public static InputStream fromBufferedImage(BufferedImage image, String format) {
        try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
            ImageIO.write(image, format, os);
            return new ByteArrayInputStream(os.toByteArray());
        } catch (IOException e) {
            log.error("BufferedImage 转换为 InputStream 失败", e);
            throw new IllegalArgumentException("BufferedImage 转换失败", e);
        }
    }

    /**
     * 从Base64转换为InputStream
     */
    public static InputStream fromBase64(String base64Data) {
        if (StrUtil.isBlank(base64Data)) {
            throw new IllegalArgumentException("Base64数据不能为空");
        }

        try {
            // 移除头部前缀（如 ）
            String data = base64Data.contains(",") ? base64Data.split(",")[1] : base64Data;

            data = data.replaceAll("\\s+", "").replace(" ", "+");

            byte[] bytes = Base64.getDecoder().decode(data);
            return new ByteArrayInputStream(bytes);
        } catch (IllegalArgumentException e) {
            log.error("Base64解码失败，原始数据前50位：{}", StrUtil.sub(base64Data, 0, 50));
            throw new IllegalArgumentException("Base64格式非法", e);
        }
    }

    /**
     * 从Base64转换为byte[]
     */
    public static byte[] fromBase64ToBytes(String base64Data) {
        if (!StringUtils.hasText(base64Data)) {
            throw new IllegalArgumentException("Base64数据不能为空");
        }
        String data = base64Data.contains(",") ? base64Data.split(",")[1] : base64Data;
        data = data.replaceAll("\\s+", "").replace(" ", "+");
        return Base64.getDecoder().decode(data);
    }

    /**
     * 将字节数组转换为Base64
     *
     * @param bytes 字节数组
     * @return Base64编码的字符串
     */
    public static String fromBytesToBase64(byte[] bytes) {
        if (bytes.length == 0) {
            throw new IllegalArgumentException("字节数组不能为空");
        }

        String fileType;
        try (InputStream inputStream = new ByteArrayInputStream(bytes)) {
            fileType = FileTypeUtil.getType(inputStream);
        } catch (Exception e) {
            log.error("读取文件类型失败", e);
            fileType = null;
        }

        String mimeType = MIME_TYPE_MAP.getOrDefault(fileType, "application/octet-stream");
        if ("application/octet-stream".equals(mimeType)) {
            log.warn("无法识别文件类型 [{}]，使用默认 MIME 类型", fileType);
        }

        String base64 = Base64.getEncoder().encodeToString(bytes);
        return "data:" + mimeType + ";base64," + base64;
    }

    /**
     * 获取文件扩展名
     */
    public static String getExtension(String fileName) {
        if (!StringUtils.hasText(fileName)) {
            return "";
        }
        int dotIndex = fileName.lastIndexOf('.');
        return dotIndex > 0 ? fileName.substring(dotIndex) : "";
    }

    /**
     * 根据文件完整路径获取文件名（包含后缀）
     *
     * @param filePath 文件完整路径，例如：/home/user/docs/file.txt
     * @return 文件名（包含后缀），例如：file.txt；若路径为空或非法则返回 null
     */
    public static String getFileNameFromPath(String filePath) {
        if (filePath == null || filePath.trim().isEmpty()) {
            log.error("文件路径不能为空");
            return null;
        }

        // 统一路径分隔符为当前系统分隔符（支持 Linux/Windows）
        filePath = filePath.replace("\\", "/");

        int lastSlashIndex = filePath.lastIndexOf("/");
        if (lastSlashIndex == -1 || lastSlashIndex == filePath.length() - 1) {
            log.error("路径不合法或不包含文件名");
            return null;
        }

        return filePath.substring(lastSlashIndex + 1);
    }
}
